package system.communication;

import system.track.Direction;
import system.track.SwitchAngle;
import system.track.Sensor;

/**
 * Defines the general behavior of classes implementing the Monitor interface.
 * 
 * @author Elliot Cash
 * @version Cycle 1 - complete
 */
public interface Monitor
{
    /**
     * Sets direction and speed attributes to a block on the track.
     * 
     * @param id an ID corresponding to the blocks on the track with a range of 1-9.
     * @param direction one of the instantiated object of the Direction enum in the track package.
     * @param speed a speed set to the specific block with a range of 0-7.
     */
    public void setBlock(int id, Direction direction, int speed);
    
    /**
     * Retrieves a block's Direction.
     * 
     * @param id an ID corresponding to the blocks on the track with a range of 1-9.
     * @return the Direction of the Block
     */
    public Direction getBlockDirection(int id);
        
    /**
     * Retreives the current speed set on a block.
     * 
     * @param id an ID corresponding to the blocks on the track with a range of 1-9.
     * @return an int representing the current set speed of the block.
     */
    public int getBlockSpeed(int id);
    
    /**
     * Sets a switch on the track to specified SwitchAngle.
     * 
     * @param id an ID corresponding to the switches on the track with a range of 1-6.
     * @param switchAngle one of the instantiated object of the SwitchAngle enum in the track package.
     */
    public void setSwitch(int id, SwitchAngle switchAngle);
    
    /**
     * Retrieves a switch's current angle.
     * 
     * @param id an ID corresponding to the switches on the track with a range of 1-6.
     * @return a SwitchAngle corresponding to the id input.
     */
    public SwitchAngle getSwitchAngle(int id);
    
    /**
     * Toggles a Switch.
     * 
     * @param id an ID corresponding to the switches on the track with a range of 1-6.
     */
    public void toggleSwitch(int id);
    
    /**
     * Sets the physical LED lights (There exist 8 individual lights on the LED) 
     * 
     * @param value an integer with a range of 0-255.
     * <table border=1><caption><i>Examples</i></caption><tr><td>Value</td><td>Binary Rep</td><td>On Lights</td></tr>
     * <tr><td>0</td><td>00000000</td><td>None</td></tr>
     * <tr><td>1</td><td>00000001</td><td>First</td></tr>
     * <tr><td>2</td><td>00000010</td><td>Second</td></tr>
     * <tr><td>5</td><td>00000101</td><td>First, Third</td></tr>
     * <tr><td>8</td><td>00001000</td><td>Fourth</td></tr>
     * <tr><td>48</td><td>00110000</td><td>Fifth, Sixth</td></tr>
     */
    public void setLED(int value);
    
    /**
     * Gets the value of the LED
     * 
     * @return an integer representing the value of the LED.
     */
    public int getLED();
    
    /**
     * Stops the train
     */
    public void stop();
    
    /**
     * This tells the monitor to send out for a HandControl message
     * 
     * @param id an integer representing the id of the HandControl
     */
    public void getHandControlStatus(int id);
        
    /**
     * Registers a sensor to the Monitor.
     *
     * @param sensor A Sensor object to be registered to the Monitor.
     */
    public void registerSensor(Sensor sensor);

    /**
     * Tests to see if there are any sensor Messages in the Monitor.
     *
     * @return a boolean value. Returns true if the Monitor contains sensor
     * Messages, and returns false if it is empty.
     */
    public boolean hasSensorMessage();

    /**
     * Retrieves the most current sensor Message in the Monitor.
     *
     * @return the last sensor Message retreived by the Listener.
     */
    public Message getSensorMessage();

    /**
     * Starts the MessageListener class.
     */
    public void startListener();
}